package com.mutouren.modules.datapush;

import java.util.HashMap;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;

import com.mutouren.common.exception.ExceptionUtils;
import com.mutouren.common.log.LogAlias;
import com.mutouren.common.log.LogManager;
import com.mutouren.common.log.Logger;
import com.mutouren.common.utils.FileUtils;
import com.mutouren.modules.datapush.base.Constant;
import com.mutouren.modules.datapush.base.PushServer;
import com.mutouren.modules.datapush.local.LocalServer;

public final class LocalManager {
	
	private static Map<String, PushServer> mapServer;
	private static String storageFolder = "";
	private volatile static boolean isOpened = false;
	
	private final static Logger errorLogger = LogManager.getLogger(LogAlias.SystemError.name());
	private final static Logger runLogger = LogManager.getLogger(LogAlias.SystemRun.name());	
	
	public static void open() {
		open("", true);
	}
	
	public static boolean isOpen() {
		return LocalManager.isOpened;
	}
	
	public synchronized static void open(String storageFolder, boolean isOpenDefaultLocalServer) {
		if (isOpened) {
			runLogger.info("LocalManager already opened");
			return;
		}
		
		runLogger.info("LocalManager open begin");
		try {
			if (!StringUtils.isBlank(storageFolder)) {
				LocalManager.storageFolder = storageFolder.trim();
				FileUtils.createFolderIfNoExist(storageFolder);
				
				for(String serverAlias : mapServer.keySet()) {
					if((isOpenDefaultLocalServer == false)&&(Constant.defaultServerAlias.equals(serverAlias))) continue;
					
					runLogger.info(String.format("server: %s open begin", serverAlias));
					mapServer.get(serverAlias).open(String.format("%s/%s.dp", LocalManager.storageFolder, serverAlias));
					runLogger.info(String.format("server: %s open end", serverAlias));
				}				
			} else {
				for(String serverAlias : mapServer.keySet()) {
					if((isOpenDefaultLocalServer == false)&&(Constant.defaultServerAlias.equals(serverAlias))) continue;
					
					runLogger.info(String.format("server: %s open", serverAlias));
					mapServer.get(serverAlias).open("");
				}
			}
			
		} catch (Throwable t) {
			errorLogger.error("LocalManager open error", t);
			throw ExceptionUtils.doUnChecked(t);
		}
		runLogger.info("LocalManager open end");
		
		isOpened = true;
	}	
	public synchronized static void close() {
		if (!isOpened) {
			runLogger.info("LocalManager already closed");
			return;
		}
		
		runLogger.info("LocalManager close begin");
		try {		
			for(String serverAlias : mapServer.keySet()) {
				runLogger.info(String.format("server: %s close begin", serverAlias));
				mapServer.get(serverAlias).close();
				runLogger.info(String.format("server: %s close end", serverAlias));
			}	
		} catch (Throwable t) {
			errorLogger.error("LocalManager close error", t);
			throw ExceptionUtils.doUnChecked(t);
		}
		runLogger.info("LocalManager close end");
		
		isOpened = false;
	}	
	public synchronized static void register(PushServer pushServer) {
		if (isOpened) {
			throw new RuntimeException("LocalManager is opened, can't register");
		}		

		if (mapServer.containsKey(pushServer.getServerAlias())) {
			throw new RuntimeException("serverAlias name already exist");
		}
		mapServer.put(pushServer.getServerAlias(), pushServer);
	}
	public synchronized static PushServer getServer(String serverAlias) {
		PushServer result = mapServer.get(serverAlias);
		if (result == null) {
			throw new RuntimeException("serverAlias name isn't exist");
		}
		
		return result;
	}
	
	static {
		mapServer = new HashMap<String, PushServer>();
		mapServer.put(Constant.defaultServerAlias, new LocalServer(Constant.defaultServerAlias));
	}
}
